//
//  File.swift
//  
//
//  Created by Hoa on 2021/6/15.
//

import UIKit

public protocol HiScrollSubContainerDelegate: AnyObject {
    
    func pageMenuContrainer(_ pageMenuContrainer: HiScrollSubContainer, willMoveTo viewController: UIViewController, at index: Int)

    func pageMenuContrainer(_ pageMenuContrainer: HiScrollSubContainer, didMoveTo viewController: UIViewController, at index: Int)
    
}

open class HiPageViewController: UIPageViewController, UIGestureRecognizerDelegate {
    
    public init() {
        let style: UIPageViewController.TransitionStyle = .scroll
        super.init(transitionStyle: style, navigationOrientation: .horizontal, options: nil)
    }
    
    required public init?(coder: NSCoder) {
        super.init(coder: coder)
    }
}

/**
 *  UIPageViewController 容器视图
 */
open class HiScrollSubContainer: UIView {
    
    open weak var delegate: HiScrollSubContainerDelegate!
    
    open lazy var pageViewController: HiPageViewController = {
        let pageViewController = HiPageViewController()
        pageViewController.delegate = self
        pageViewController.dataSource = self
        return pageViewController
    }()
    
    public var childControllers: [UIViewController]!
    public var currentIndex = 0
    private var dataCenter: HiScrollContainerSectionDelegate!

    public init(_ childControllers: [UIViewController], parent: UIViewController, dataCenter: HiScrollContainerSectionDelegate) {
        super.init(frame: .zero)
        self.childControllers = childControllers
        self.currentIndex = dataCenter.selectedIndex
        self.dataCenter = dataCenter
        
        parent.addChild(pageViewController)
        self.addSubview(pageViewController.view)
        pageViewController.view.translatesAutoresizingMaskIntoConstraints = false
        
        if let subView = pageViewController.view {
            self.addConstraint(.init(item: subView, attribute: .left, relatedBy: .equal, toItem: self, attribute: .left, multiplier: 1, constant: 0))
            
            self.addConstraint(.init(item: subView, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1, constant: 0))
            
            self.addConstraint(.init(item: subView, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1, constant: 0))
            
            self.addConstraint(.init(item: subView, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1, constant: 0))
             pageViewController.didMove(toParent: parent)
        }
        changeMenuItem(at: dataCenter.selectedIndex)
    }
    
    required public init?(coder: NSCoder) {
        super.init(coder: coder)
    }

    private func changeMenuItem(at index: Int) {
        let viewController: UIViewController = self.childControllers[index]
        let viewControllers: [UIViewController] = [viewController]
        let direction: UIPageViewController.NavigationDirection = (index > currentIndex) ? .forward : .reverse
        self.currentIndex = index
        pageViewController.setViewControllers(viewControllers, direction: direction, animated: true, completion: nil)
    }
}
extension HiScrollSubContainer: HiScrollContainerSectionDelegate {
    
    open func setIndex(_ index: Int) {
        selectedIndex = index
        changeMenuItem(at: index)
    }
    
    open var selectedIndex: Int {
        get {
            self.currentIndex
        }
        set {
            self.currentIndex = newValue
        }
    }
    
    
}

// MARK:  UIPageViewControllerDelegate, UIPageViewControllerDataSource
extension HiScrollSubContainer: UIPageViewControllerDelegate, UIPageViewControllerDataSource {
    
    // MARK - UIPageViewControllerDelegate (optional)
    open func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
        if let viewController: UIViewController = pendingViewControllers.last {
            if let index = self.childControllers?.firstIndex(of: viewController) {
                delegate?.pageMenuContrainer(self, willMoveTo: viewController, at: index)
            }
        }
    }
    
    // MARK - UIPageViewControllerDelegate (optional)
    open func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
        if let viewController: UIViewController = pageViewController.viewControllers?.last {
            guard let index = self.childControllers.firstIndex(of: viewController) else { return }
            if completed {
                currentIndex = index
            }
            else {

            }
            delegate?.pageMenuContrainer(self, didMoveTo: viewController, at: index)
            dataCenter.setIndex(index)
        }
    }
    
    // MARK - UIPageViewControllerDelegate (optional)
    open func pageViewController(_ pageViewController: UIPageViewController, spineLocationFor orientation: UIInterfaceOrientation) -> UIPageViewController.SpineLocation {
        if orientation.isPortrait || UIDevice.current.userInterfaceIdiom == .phone {
            if let currentViewController: UIViewController = pageViewController.viewControllers?.first {
                let viewControllers: [UIViewController] = [currentViewController]
                pageViewController.setViewControllers(viewControllers, direction: .forward, animated: true, completion: nil)
            }
            pageViewController.isDoubleSided = false
            return .min
        }
        return .none
    }
    
    
    // MARK - UIPageViewControllerDataSource (required)
    open func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        if let index = self.childControllers.firstIndex(of: viewController) {
            if index != 0 && index != NSNotFound {
                return self.childControllers[index - 1]
            }
        }
        return nil
    }
    
    // MARK - UIPageViewControllerDataSource (required)
    open func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        if let index = self.childControllers.firstIndex(of: viewController) {
            let count: Int = self.childControllers.count
            if index != NSNotFound && index + 1 < count {
                return self.childControllers[index + 1]
            }
        }
        return nil
    }
    
}
